package com.xbongbong.saas.service.impl;

import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.help.FormDataValidateProductHelp;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.outstockproduct.pojo.dto.OutstockProductDeleteBatchDTO;
import com.xbongbong.pro.outstockproduct.pojo.dto.OutstockProductListDTO;
import com.xbongbong.pro.outstockproduct.pojo.vo.OutstockProductDeleteBatchVO;
import com.xbongbong.pro.outstockproduct.pojo.vo.OutstockProductListVO;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.domain.entity.OutstockProductEntity;
import com.xbongbong.saas.domain.entity.ProductStockUpdateEntity;
import com.xbongbong.saas.help.workflow.OutstockHelp;
import com.xbongbong.saas.model.OutstockProductModel;
import com.xbongbong.saas.model.ProductStockModel;
import com.xbongbong.saas.model.ProductWarehouseModel;
import com.xbongbong.saas.service.OutstockProductService;
import com.xbongbong.saas.service.OutstockService;
import com.xbongbong.saas.service.ProductSerialService;
import com.xbongbong.sys.model.CompanyConfigModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author 吴峰
 * @version v1.0
 * @date 2019/3/1 22:20
 * @since v1.0
 */
@Service("outstockProductService")
public class OutstockProductServiceImpl implements OutstockProductService {

    private static final Logger LOG = LoggerFactory.getLogger(OutstockProductServiceImpl.class);

    @Resource
    private OutstockProductModel outstockProductModel;
    @Resource
    private ProductWarehouseModel productWarehouseModel;
    @Resource
    private OutstockService outstockService;
    @Resource
    private ProductStockModel productStockModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private FormDataValidateProductHelp formDataValidateProductHelp;
    @Resource
    private ProductSerialService productSerialService;
    @Resource
    private OutstockHelp outstockHelp;

    @Override
    public List<OutstockProductEntity> getAlreadyOutstockProduct(String corpid, Long refId, Integer type) throws XbbException {
        PaasFormDataEsListVO outstockListFromEs = outstockService.getOutstockListFromEs(corpid, refId, type, 0);
        List<PaasFormDataEntityExt> paasFormDataESList = outstockListFromEs.getPaasFormDataESList();
        List<Long> outstockIdIn = new ArrayList<>();
        paasFormDataESList.forEach(paasFormDataEntityExt -> outstockIdIn.add(paasFormDataEntityExt.getId()));
        Map<String ,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put("outstockIdIn", outstockIdIn);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<OutstockProductEntity> entitys = outstockProductModel.findEntitys(param);
        Collection<OutstockProductEntity> mergeOutstockProduct = outstockProductModel.mergeOutstockProduct(entitys);
        entitys.clear();
        entitys.addAll(mergeOutstockProduct);
        return entitys;
    }

    @Override
    public OutstockProductListVO findOutstockProduct(OutstockProductListDTO outstockProductListDTO) throws XbbException {
        OutstockProductListVO outstockProductListVO = new OutstockProductListVO();
        try {
            Map<String, Object> param = BeanUtil.convertBean2Map(outstockProductListDTO, true);
            List<OutstockProductEntity> outstockProductList = outstockProductModel.findEntitys(param);
            if (Objects.isNull(outstockProductList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            outstockProductListVO.setOutstockProductList(outstockProductList);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("outstockProductServiceImpl.findOutstockProduct 查询出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return outstockProductListVO;
    }

    @Override
    public OutstockProductDeleteBatchVO deleteBatchByOutstockIdIn(OutstockProductDeleteBatchDTO outstockProductDeleteBatchDTO) throws XbbException {
        OutstockProductDeleteBatchVO outstockProductDeleteBatchVO = new OutstockProductDeleteBatchVO();
        try {
            List<Long> outstockIdIn = outstockProductDeleteBatchDTO.getOutstockIdIn();
            String corpid = outstockProductDeleteBatchDTO.getCorpid();
            Map<String, Object> param = BeanUtil.convertBean2Map(outstockProductDeleteBatchDTO, true);
            param.put("del", DelEnum.NORMAL.getDel());
            List<OutstockProductEntity> outstockProductList = outstockProductModel.findEntitys(param);
            if (Objects.isNull(outstockProductList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            if (Objects.nonNull(outstockIdIn) && !outstockIdIn.isEmpty()) {
                // 删除入库单产品更新产品序列号信息
                productSerialService.deleteSerial(corpid, outstockIdIn, outstockProductDeleteBatchDTO.getBusinessType());
                outstockProductModel.deleteByOutstockIdIn(corpid, outstockIdIn);
            }
            outstockProductDeleteBatchVO.setOutstockProductList(outstockProductList);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("outstockProductServiceImpl.deleteBatch 查询出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return outstockProductDeleteBatchVO;
    }
    @Override
    public Map<Long, ProductStockUpdateEntity> delUpdateStock(List<OutstockProductEntity> outstockProductList, String corpid, Set<Long> disableBatchProducts) throws XbbException {
        Map<Long,ProductStockUpdateEntity> productUpdateMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, ProductStockUpdateEntity> warehouseProductUpdateMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, ProductStockUpdateEntity> batchProductUpdateMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Boolean batchShelf = companyConfigModel.getBatchShelf(corpid);
        for (OutstockProductEntity entity : outstockProductList){
            if (Objects.equals(entity.getProductDel(),1) || Objects.equals(entity.getWarehouseDel(),1)) {
                //产品删除或者仓库删除不需要更新库存
                continue;
            }
            Double amendNum = entity.getProductNum() == null ? 0D : entity.getProductNum();
            Double amendCost = entity.getCost() == null ? 0D : entity.getCost();
            Long productId = entity.getProductId();
            String warehouseKey = productId + "_" + entity.getWarehouseId();
            // 全仓库存数据
            String allWarehouseKey = productId + "_" + 0;
            if (productUpdateMap.containsKey(entity.getProductId())){
                ProductStockUpdateEntity productStockUpdateEntity = productUpdateMap.get(entity.getProductId());
                productStockUpdateEntity.updateStock(amendNum,amendCost);
                productUpdateMap.put(entity.getProductId(),productStockUpdateEntity);
            }else {
                ProductStockUpdateEntity productStockUpdateEntity = new ProductStockUpdateEntity(productId,amendNum,amendCost);
                productUpdateMap.put(entity.getProductId(),productStockUpdateEntity);
            }
            //分仓数量
            if (warehouseProductUpdateMap.containsKey(warehouseKey)){
                ProductStockUpdateEntity productStockUpdateEntity = warehouseProductUpdateMap.get(warehouseKey);
                productStockUpdateEntity.updateStock(amendNum,amendCost);
                warehouseProductUpdateMap.put(warehouseKey,productStockUpdateEntity);
            }else {
                ProductStockUpdateEntity productStockUpdateEntity = new ProductStockUpdateEntity(warehouseKey,amendNum,amendCost);
                warehouseProductUpdateMap.put(warehouseKey,productStockUpdateEntity);
            }
            //总仓数量
            if (warehouseProductUpdateMap.containsKey(allWarehouseKey)){
                ProductStockUpdateEntity productStockUpdateEntity = warehouseProductUpdateMap.get(allWarehouseKey);
                productStockUpdateEntity.updateStock(amendNum,amendCost);
                warehouseProductUpdateMap.put(allWarehouseKey,productStockUpdateEntity);
            }else {
                ProductStockUpdateEntity productStockUpdateEntity = new ProductStockUpdateEntity(allWarehouseKey,amendNum,amendCost);
                warehouseProductUpdateMap.put(allWarehouseKey,productStockUpdateEntity);
            }
            //公司级配置没有开启批次或者单个产品没有开启批次的话不需要跟新批次库存
            if (Objects.nonNull(entity.getBatch()) && batchShelf && !disableBatchProducts.contains(entity.getParentId())) {
                //批次数量
                String batchKey = formDataValidateProductHelp.getBatchKey(productId, entity.getWarehouseId(), entity.getBatch(), entity.getProduceDate(), entity.getGuaranteePeriod());
                if (batchProductUpdateMap.containsKey(batchKey)){
                    ProductStockUpdateEntity productStockUpdateEntity = batchProductUpdateMap.get(batchKey);
                    productStockUpdateEntity.updateStock(amendNum,amendCost);
                    batchProductUpdateMap.put(batchKey,productStockUpdateEntity);
                }else {
                    ProductStockUpdateEntity productStockUpdateEntity = new ProductStockUpdateEntity(batchKey,amendNum,amendCost);
                    batchProductUpdateMap.put(batchKey,productStockUpdateEntity);
                }
            }
        }
        productStockModel.updateStockDB(batchProductUpdateMap.keySet(), batchProductUpdateMap.values(),corpid);
        productWarehouseModel.updateStockDB(warehouseProductUpdateMap.keySet(), warehouseProductUpdateMap.values(),corpid, false);
        return productUpdateMap;
    }

    @Override
    public Map<Long, ProductStockUpdateEntity> addUpdateStock(List<OutstockProductEntity> outstockProductList, String corpid) throws XbbException {
        return outstockHelp.addUpdateStock(outstockProductList, corpid);
    }
}
